import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;

/**
 * An object representing the number to guess.
 *
 * A model controls access to the data.  Another class should never
 * have direct access to this data.
 */
class GuessModel {
	private static final Random generator = new Random();
	private static int number;

	/**
	 * Generates a random number between 1 and 10.
	 */
	public void randomize() {
		number = generator.nextInt(10) + 1;
	}

	/**
	 * Provides a string indicating whether or not the guess was
	 * correct.
	 * 
	 * @param guess The user's guess.
	 *
	 * @return A message indicating either success or failure.  If
	 * failure, the user is told which direction to go.
	 */
	public String react(int guess) {
		if (guess > number) {
			return "The number is too high.  Try a lower number.";
		} else if (guess < number) {
			return "The number is too low.  Try a higher number.";
		} else {
			return "Correct!";
		}
	}
}

/**
 * An object representing the user interface.
 *
 * The JFrame class implements a window.  Since in this case the
 * view is representing by a GUI window, we extend the JFrame class.
 */
class GuessView extends JFrame {
	JTextField guess;
	JLabel instructions;
	JLabel result;
	JButton newGame;

	JPanel content;

	public GuessView(String title) {
		this.setTitle(title);

		// We initialize all of the widgets.
		this.guess = new JTextField(5);
		this.instructions = new JLabel("Enter a number between 1 and 10");
		this.result = new JLabel("");
		this.newGame = new JButton("New Game");

		// This panel makes up the contents of the window.  We add the
		// widgets to it.
		this.content = new JPanel();
		this.content.add(this.instructions);
		this.content.add(this.result);
		this.content.add(this.guess);
		this.content.add(this.newGame);

		// This tells our JFrame object which panel to use for its contents,
		// uses the layout manager (FlowLayout by default) to place the
		// widgets, makes the window visible, and tells Swing to close the
		// application when the close button is clicked.
		this.setContentPane(this.content);
		this.pack();
		this.setVisible(true);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}

	/**
	 * Wires together the action listeners.
	 *
	 * When an event is triggered, we need to be able to query the
	 * ActionListener object to determine which event occurred.  To do this
	 * we specify an action command.
	 *
	 * @param al The action listener to bind to.
	 */
	public void buttonActionListeners(ActionListener al) {
		this.guess.setActionCommand("number");
		this.guess.addActionListener(al);

		this.newGame.setActionCommand("newgame");
		this.newGame.addActionListener(al);
	}
}

/**
 * An object representing the controller.
 *
 * A controller responds to events triggered in the view.  It provides
 * a way to update the model and updates the view.  In order to respond
 * to events, we implement the ActionListener interface.
 */
class GuessController implements ActionListener {
	private GuessModel model;
	private GuessView view;

	public GuessController(GuessModel model, GuessView view) {
		this.model = model;
		this.view = view;

		this.view.buttonActionListeners(this);
		this.model.randomize();
	}

	/**
	 * Whenever an action is performed, this method is called.
	 *
	 * This method uses the command for each action set in the view in
	 * order to determine what to do.
	 *
	 * @param ae The event details.
	 */
	public void actionPerformed(ActionEvent ae) {
		// Grab a string representing the action's command.
		String action = ae.getActionCommand();

		// If the user wants to begin a new game, reset the text box and
		// generate a new random number.
		if (action.equals("newgame")) {
			this.view.result.setText("Please enter in a guess");

			this.view.guess.setText("");
			this.view.guess.setEditable(true);

			this.model.randomize();
		// If the user guesses a number, see if it's correct.  If it is,
		// disable the guessing text box so they must create a new game to
		// proceed.
		} else if (action.equals("number")) {
			int guess = Integer.parseInt(this.view.guess.getText());
			String reaction = this.model.react(guess);
			this.view.result.setText(reaction);

			if (reaction.equals("Correct!")) {
				this.view.guess.setEditable(false);
			}
		}
	}
}

public class Guess {
	public static void main(String[] args) {
		GuessModel model = new GuessModel();
		GuessView view = new GuessView("Guessing Game");
		GuessController controller = new GuessController(model, view); 
	}
}
